<html>

<style>
    * {
        margin: 0;
    }

    #content {
        color: white;
        position: absolute;
        left: -20px;
        top: -10px;
        white-space: pre;
        height: 200px;
        overflow: auto;
    }
</style>

<script type="importmap">
	{
	  "imports": {
		"three": "../../three.js-r151/build/three.module.js",
		"three/addons/": "../../three.js-r151/examples/jsm/"
	  }
	}
</script>

<body>
    <div id="content">
        new THREE.CameraHelper(light.shadow.camera);
        new THREE.DirectionalLightHelper(light, 1);
    </div>

    <div id="canvas"></div>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

        // 1. 创建三大件
        // 1.1 三维场景Scene, 类似创建了个世界，三维世界
        const scene = new THREE.Scene();
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        // MeshBasicMaterial MeshLambertMaterial MeshPhongMaterial
        const material = new THREE.MeshPhongMaterial({
            color: 0x00ffff, //设置材质颜色
            transparent: false,//开启透明
            opacity: 0.5,//设置透明度
        });

        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(0, 0.5, 0)
        scene.add(mesh)

        const mesh2 = new THREE.Mesh(geometry, material);
        mesh2.position.set(0, 0.5, 2)
        scene.add(mesh2)

        // 添加辅助坐标系
        const axesHelper = new THREE.AxesHelper(10);
        scene.add(axesHelper);

        // 1.2 相机
        const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
        camera.position.set(0, 10, 5)

        // 1.3 渲染器
        const renderer = new THREE.WebGLRenderer({
            antialias: true,
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        let canvasDom = document.getElementById("canvas");
        canvasDom.appendChild(renderer.domElement);

        // 设置相机控件轨道控制器OrbitControls
        const controls = new OrbitControls(camera, canvasDom);

        {
            // 2. 添加地板ground
            const mesh = new THREE.Mesh(
                new THREE.PlaneGeometry(10, 10),
                new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false }));
            mesh.rotation.x = - Math.PI / 2;
            mesh.receiveShadow = true;
            scene.add(mesh);
        }


        // 3. 打光 PointLight DirectionalLight HemisphereLight
        // 此处helper先只研究平行光
        let light;
        let lightHelper;
        {
            light = new THREE.DirectionalLight(0xffffff, 1.0);
            // light = new THREE.HemisphereLight(0xffffff, 0xccccc, 1.0);
            // light = new THREE.AmbientLight (0xffffff, 1.0);
            light.position.set(3, 4, 0);
            scene.add(light);

            // 平行光阴影相机属性.shadow.camera的属性值是一个正投影相机对象OrthographicCamera。
            console.log('阴影相机属性', light.shadow.camera);
            console.log('光', light);
            // 可以重新定义正投影相机参数
            light.shadow.camera.top = 2;
            light.shadow.camera.bottom = - 2;
            light.shadow.camera.left = - 4;
            light.shadow.camera.right = 4;
            light.shadow.camera.near = 0.1;
            // light.shadow.camera.far = 10;

            // helper2： cameraHelper
            // 此处不是 DirectionalLight, 竟然是阴影camera的Helper?
            let cameraHelper = new THREE.CameraHelper(light.shadow.camera);
            // scene.add(cameraHelper);
            lightHelper = cameraHelper;


            // mapSize属性阴影贴图，太小了会有齿轮感觉，默认512x512，默认的也不好看，阴影不模糊
            console.log('阴影默认像素', light.shadow.mapSize);
            // light.shadow.mapSize.set(50, 50)

            // radius阴影边缘 默认1
            console.log('.shadow.radius',light.shadow.radius);
            light.shadow.radius = 10
        }


        // DirectionalLightHelper和SpotLightHelper用法是一模一样的
        // 参数2表示平行光.position附近方框的尺寸
        const dirHelper = new THREE.DirectionalLightHelper(light, 1);
        // scene.add( dirHelper );
        

        {
            // 4. 设置阴影
            // 1. 设置产生投影的网格模型
            mesh.castShadow = true;
            // 2. 光设置产生阴影的光源对象,开启光源阴影的计算功能
            light.castShadow = true;
            // 3.1 ground设置接收阴影的投影面
            // 3.2 mesh2也能接受阴影
            mesh2.receiveShadow = true;
            // 设置渲染器，允许光源阴影渲染
            renderer.shadowMap.enabled = true;
        }

        let R = 3;
        let angle = 0;
        function render() {
            // 点光源光源旋转
            // angle += 0.005
            // lightWithShadow.position.x = R * Math.sin(angle)
            // lightWithShadow.position.z = R * Math.cos(angle)
            // spotLightHelper.update()

            // 平行光的旋转到是简单了, 因为阴影相机本身就是在light中的， 
            angle += 0.005
            light.position.x = R * Math.sin(angle)
            light.position.z = R * Math.cos(angle)
            dirHelper.update();


            renderer.render(scene, camera);
            requestAnimationFrame(render)
        }
        render()

    </script>
</body>

</html>